/*示例首先使用 fork()创建了一个子进程，接着为了保证子进程不在父进程调用 kill()之前退出，在
子进程中使用 raise()函数向自身发送 SIGSTOP 信号，使子进程暂停。接下来再在父进程中调用 kill()向子
进程发送信号，在该示例中使用的是 SIGKILL，读者可以使用其他信号进行练习。*/


#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

/*信号发送与捕捉    ,信号处理*/

#define RUN_DEMO  3   /*DEMO1:kill()和 raise() ;  DEMO2:alarm()和 pause()    DEMO3:表明了如何使用 signal()函数捕捉相应信号，并做出给定的处理。*/


#if  (RUN_DEMO==1)
int main()
{
	pid_t pid;
	int ret;

	/*创建一子进程*/

	if((pid = fork()) < 0)
	{
		printf("Fork error \n");
		exit(1);
	}
	printf("The PID of this process is %d\n",getpid());/*打印输出当前进程的进程ID*/
	printf("The PPID of this process is %d\n",getppid());/*打印父进程ID*/

	if(pid == 0)
	{
		/*在进程中使用raise()函数发出SIGSTOP信号，使子进程暂停*/

		printf("Child(pid : %d) is waiting for any signal \n",getpid());
		raise(SIGSTOP);
		exit(0);
	}
	else
	{
		/*在父进程中收集子进程发出的信号，并调用kill()函数进行相应的操作*/
		if((waitpid(pid,NULL,WNOHANG)) ==0)
		{
			if((ret = kill(pid,SIGKILL)) == 0)
			{
				printf("Parent kill %d\n",pid);
			}
		}
		waitpid(pid,NULL,0);
		exit(0);
	}
}

#endif


#if(RUN_DEMO==2)

int main()
{
	/*调用alarm 定时器函数*/

	int ret = alarm(5);
	pause();
	printf("I have been waken up .\n",ret);
}

#endif

/*如何使用 signal()函数捕捉相应信号，并做出给定的处理*/
#if(RUN_DEMO==3)

/*自定义信号处理函数*/
void my_func(int sign_no)
{
	if(sign_no ==SIGINT)
	{
		printf("I have get SIGINT\n");
	}
	else if(sign_no == SIGQUIT)
	{
		printf("I have get SIGQUIT \n");
	}
}

int main()
{
	printf("Waiting for signal SIGINT or SIGQUIT... \n");
	
	/*发出相应的信号，并跳转到信号处理函数处*/

	signal(SIGINT,my_func);
	signal(SIGQUIT,my_func);

	pause();//挂起当前进程，直到收到信号为止

	exit(0);
}



#endif

